/***************************************************************************
 *   Copyright (C) 2007 by Anders Nore 																		 *
 *   andenore@start.no   																									 *
 *                                                                         *
 *   Permission is hereby granted, free of charge, to any person obtaining *
 *   a copy of this software and associated documentation files (the       *
 *   "Software"), to deal in the Software without restriction, including   *
 *   without limitation the rights to use, copy, modify, merge, publish,   *
 *   distribute, sublicense, and/or sell copies of the Software, and to    *
 *   permit persons to whom the Software is furnished to do so, subject to *
 *   the following conditions:                                             *
 *                                                                         *
 *   The above copyright notice and this permission notice shall be        *
 *   included in all copies or substantial portions of the Software.       *
 *                                                                         *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       *
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    *
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR     *
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
 *   OTHER DEALINGS IN THE SOFTWARE.                                       *
 ***************************************************************************/
#ifndef __UNP_H
#define __UNP_H

#include <sys/socket.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/wait.h>
#include <sys/select.h>
#include <sys/ioctl.h>   /** @brief ioctl definition may be in <unistd.h> on some implementations */
#include <sys/sysctl.h>
#include <netinet/in.h>
#include <net/if.h>
#include <netdb.h>
#include <unistd.h>
#include <stdarg.h>
#include <signal.h>
#include <errno.h>

#ifdef THREADED
#include <pthread.h>
#endif /* THREADED */

#ifdef __FREEBSD_
#include <ifaddrs.h>	/** getifaddrs(), freebsd function to get a list of all interfaces */
#endif

/* Constants */
#define LISTENQ 15

/* Macros */
#define forever() for(;;)


// #ifndef IP_BLOCK_SOURCE
// 
// /* These constants were taken from FreeBSD 6.2 netinet/in.h */
// #define IP_BLOCK_SOURCE 72
// #define IP_UNBLOCK_SOURCE 73
// 
// struct ip_mreq_source {
// 	struct in_addr imr_multiaddr;
// 	struct in_addr imr_sourceaddr;
// 	struct in_addr imr_interface;
// };
// 
// #endif


/* Typedefs */
typedef struct sockaddr SA;			/* makes arguments shorter(just for looks) */
typedef void (*Sigfunc)(int);		/* used in signal(), pointer to function */

int Socket(int domain, int type, int protocol);
int Bind(int s, const struct sockaddr *addr, socklen_t addrlen);
int Listen(int s, int backlog);
int Accept(int s, struct sockaddr * addr, socklen_t * addrlen);
int Connect(int s, const struct sockaddr *name, socklen_t namelen);
int Shutdown(int s, int how);
int Tcp_connect( const char *hostname, const char *service );   // Connect to a tcp server
int Tcp_listen(char *hostname, char *service, socklen_t *len);  // Create a tcp listen server (SO_REUSEADDR sockopt)
int Udp_client( const char *hostname, const char *service, SA **saptr, socklen_t *lenp); // makes an unconnected udp socket
int Udp_connect( const char *hostname, const char *service ); // a connected udp socket
int Udp_server(char *hostname, char *service, socklen_t *len); // an udp server

/* Multicast */
void Mcast_join(int sockfd, const SA *grp, socklen_t grplen, const char *ifname, const char *str_addr);
void Mcast_leave(int sockfd, const SA *grp, socklen_t grplen, const char *ifname, const char *str_addr);
// void Mcast_block_source(int sockfd, struct sockaddr *grp, const char *block_ip, const char *local_ip);
void Mcast_enable_loop(int sockfd, int value);

ssize_t Write(int d, const void *buf, size_t nbytes);
ssize_t Read(int d, const void *buf, size_t nbytes);

void *Malloc(size_t size);

int Select(int nfds, fd_set *readfds, fd_set *writefds,
		    fd_set *exceptfds, struct timeval *timeout);
const char *Inet_ntop(socklen_t len, const void * src, char * dst, socklen_t size);
const char *Sock_ntop(const SA *sa, socklen_t salen);
int Sock_pton(const char *string, void *dst);

//char *net_rt_iflist(int family, int flags, size_t *lenp);

void err_quit(char *msg, ...);
void err_sys(char *msg, ...);

#endif

